|
Package MDSplus ::
Module compound
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 -def _mimport(name, level=1):
27 try:
28 return __import__(name, globals(), level=level)
29 except:
30 return __import__(name, globals())
31
32 import ctypes as _C
33 import numpy as _N
34
35 _ver=_mimport('version')
36 _dsc=_mimport('descriptor')
37 _dat=_mimport('mdsdata')
38 _tre=_mimport('tree')
39 _exc=_mimport('mdsExceptions')
42
44 """MDSplus compound data."""
45 if len(args)==1 and args[0] is self: return
46 if self.__class__ is Compound:
47 raise TypeError("Cannot create instances of class Compound")
48 self._fields={}
49 for idx in range(len(self.fields)):
50 self._fields[self.fields[idx]]=idx
51 self._argOffset=len(self.fields)
52 self.setDescs(args)
53 for k,v in kwargs:
54 if k in self.fields:
55 self.setDescAt(self._fields[k],v)
56
58 return '%s(%s)'%(self.__class__.__name__,','.join([str(d) for d in self.getDescs()]))
59
60 @property
67
68 @property
70 for arg in self._args:
71 if isinstance(arg,_dat.Data):
72 tree=arg.tree
73 if tree is not None:
74 return tree
75 return None
76 @tree.setter
77 - def tree(self,tree):
78 for arg in self._args:
79 if isinstance(arg,_dat.Data):
80 arg._setTree(tree)
81
87
94
96 if name == '_fields':
97 return {}
98 if name in self._fields:
99 return self.getDescAt(self._fields[name])
100 elif name.startswith('get') and name[3:].lower() in self._fields:
101 def getter():
102 return self._args[self._fields[name[3:].lower()]]
103 return getter
104 elif name.startswith('set') and name[3:].lower() in self._fields:
105 def setter(value):
106 self.__setattr__(name[3:].lower(),value)
107 return setter
108 return super(Compound,self).__getattribute__(name)
109
110
113
119
122
124 """Return argument at index idx (indexes start at 0)
125 @rtype: Data,None
126 """
127 return self.getDescAt(self._argOffset+idx)
128
130 """Return arguments
131 @rtype: Data,None
132 """
133 return self.getDescAt(slice(self._argOffset,None))
134
136 """Return descriptor with index idx (first descriptor is 0)
137 @rtype: Data
138 """
139 if isinstance(idx, (slice,)):
140 return tuple(self._args[idx])
141 if idx<len(self._args) or idx>255:
142 return self._args[idx]
143 return None
144
146 """Return descriptors or None if no descriptors
147 @rtype: tuple,None
148 """
149 return tuple(self._args)
150
152 """Return number of descriptors
153 @rtype: int
154 """
155 return len(self._args)
156
158 """Set argument at index idx (indexes start at 0)"""
159 return self.setDescAt(self._argOffset+idx, value)
160
162 """Set arguments
163 @type args: tuple
164 """
165 self._args = self._args[:self._argOffset+len(args)]
166 return self.setDescAt(slice(self._argOffset,None),args)
167
169 """Set descriptor at index idx (indexes start at 0)"""
170 if isinstance(idx,slice):
171 indices=idx.indices(idx.start+len(value))
172 idx = 0
173 for i in range(indices[0],indices[1],indices[2]):
174 self.setDescAt(i,value[idx])
175 idx += 1
176 else:
177 if value is None:
178 if len(self._args) > idx:
179 self._args[idx] = None
180 else:
181 if len(self._args) <= idx:
182 self._args+=[None]*(idx-len(self._args)+1)
183 self._args[idx]=_dat.Data(value)
184 return self
185
187 """Set descriptors
188 @type args: tuple
189 """
190 self._args = [_dat.Data(arg) for arg in args]
191 while self.getNumDescs()<self._argOffset:
192 self._args.append(None)
193
194 @staticmethod
216
217 @property
231
232 @classmethod
234 args = [_dsc.pointerToObject(d.dscptrs[i],d.tree) for i in _ver.xrange(d.ndesc)]
235 ans=cls(*args)
236 if d.length>0:
237 if d.length == 1:
238 opcptr=_C.cast(d.pointer,_C.POINTER(_C.c_uint8))
239 elif d.length == 2:
240 opcptr=_C.cast(d.pointer,_C.POINTER(_C.c_uint16))
241 else:
242 opcptr=_C.cast(d.pointer,_C.POINTER(_C.c_uint32))
243 ans.opcode = opcptr.contents.value
244 return ans._setTree(d.tree)
245
247 """
248 An Action is used for describing an operation to be performed by an
249 MDSplus action server. Actions are typically dispatched using the
250 mdstcl DISPATCH command
251 """
252 fields=('dispatch','task','errorLog','completionMessage','performance')
253 dtype_id=202
254 _dsc.addDtypeToClass(Action)
255
256 -class Call(Compound):
257 """
258 A Call is used to call routines in shared libraries.
259 """
260 fields=('image','routine')
261 dtype_id=212
268 _dsc.addDtypeToClass(Call)
271 """A Conglom is used at the head of an MDSplus conglomerate. A conglomerate is a set of tree nodes used
272 to define a device such as a piece of data acquisition hardware. A conglomerate is associated with some
273 external code providing various methods which can be performed on the device. The Conglom class contains
274 information used for locating the external code.
275 """
276 fields=('image','model','name','qualifiers')
277 dtype_id=200
279 if not self.image=='__python__':
280 raise _exc.DevNOT_A_PYDEVICE
281 model = str(self.model)
282 safe_env = {}
283 qualifiers = self.qualifiers.data()
284 if isinstance(qualifiers,_N.generic): qualifiers = qualifiers.tolist()
285 if isinstance(qualifiers,list): qualifiers = ';'.join(qualifiers)
286 if isinstance(qualifiers,_ver.basestring):
287 try: exec(compile(qualifiers,'<string>','exec'),{'Device':_tre.Device},safe_env)
288 except: pass
289 if model in safe_env:
290 cls = safe_env[model]
291 else:
292 cls = _tre.Device.PyDevice(model)
293 if issubclass(cls,(_tre.Device,)):
294 return cls if len(args)+len(kwargs)==0 else cls(*args,**kwargs)
295 raise _exc.DevPYDEVICE_NOT_FOUND
296 _dsc.addDtypeToClass(Conglom)
299 """A Dependency object is used to describe action dependencies. This is a legacy class and may not be recognized by
300 some dispatching systems
301 """
302 fields=('arg1','arg2')
303 dtype_id=208
304 _dsc.addDtypeToClass(Dependency)
307 """A dimension object is used to describe a signal dimension, typically a time axis. It provides a compact description
308 of the timing information of measurements recorded by devices such as transient recorders. It associates a Window
309 object with an axis. The axis is generally a range with possibly no start or end but simply a delta. The Window
310 object is then used to bracket the axis to resolve the appropriate timestamps.
311 """
312 fields=('window','axis')
313 dtype_id=196
314 _dsc.addDtypeToClass(Dimension)
317 """A Dispatch object is used to describe when an where an action should be dispatched to an MDSplus action server.
318 """
319 fields=('ident','phase','when','completion')
320 dtype_id=203
321
323 if len(args)==1 and args[0] is self: return
324 if 'type' in kwargs:
325 self.opcode=kwargs['type']
326 else:
327 self.opcode=2
328 super(Dispatch,self).__init__(*args,**kwargs)
329 _dsc.addDtypeToClass(Dispatch)
332 """A Function object is used to reference builtin MDSplus functions. For example the expression 1+2
333 is represented in as Function instance created by Function(opcode='ADD',args=(1,2))
334 """
335 fields=tuple()
336 dtype_id=199
337 opcodeToClass={}
338
339 @classmethod
341 opc = _C.cast(d.pointer,_C.POINTER(_C.c_uint16)).contents.value
342 args = [_dsc.pointerToObject(d.dscptrs[i],d.tree) for i in _ver.xrange(d.ndesc)]
343 return cls.opcodeToClass[opc](*args)
344
346 """Create a compiled MDSplus function reference.
347 Number of arguments allowed depends on the opcode supplied.
348 """
349 if len(args)==1 and args[0] is self: return
350 if len(args)>self.max_args or (self.max_args>0 and len(args)<self.min_args):
351 if self.max_args==0 or self.max_args==self.min_args:
352 raise TypeError("Requires %d input arguments for %s but %d given"%(self.max_args,self.__class__.__name__,len(args)))
353 else:
354 raise TypeError("Requires %d to %d input arguments for %s but %d given"%(self.min_args,self.max_args,self.__class__.__name__,len(args)))
355 super(Function,self).__init__(*args)
356 @classmethod
358 if cls.__name__.startswith('d'):
359 return '$%s'%cls.__name__[1:]
360 return cls.__name__
361 _dsc.addDtypeToClass(Function)
364 """A Method object is used to describe an operation to be performed on an MDSplus conglomerate/device
365 """
366 fields=('timeout','method','object')
367 dtype_id=207
368 _dsc.addDtypeToClass(Method)
371 """A Procedure is a deprecated object
372 """
373 fields=('timeout','language','procedure')
374 dtype_id=206
375 _dsc.addDtypeToClass(Procedure)
378 """A Program is a deprecated object"""
379 fields=('timeout','program')
380 dtype_id=204
381 _dsc.addDtypeToClass(Program)
382
383 -class Range(Compound):
384 """A Range describes a ramp. When used as an axis in a Dimension object along with a Window object it can be
385 used to describe a clock. In this context it is possible to have missing begin and ending values or even have the
386 begin, ending, and delta fields specified as arrays to indicate a multi-speed clock.
387 """
388 fields=('begin','ending','delta')
389 dtype_id=201
390 @property
393 _dsc.addDtypeToClass(Range)
396 """A Routine is a deprecated object"""
397 fields=('timeout','image','routine')
398 dtype_id=205
399 _dsc.addDtypeToClass(Routine)
402 """A Signal is used to describe a measurement, usually time dependent, and associated the data with its independent
403 axis (Dimensions). When Signals are indexed using s[idx], the index is resolved using the dimension of the signal
404 """
405 fields=('value','raw')
406 dtype_id=195
407
408 @property
410 """The dimensions of the signal"""
411 return self.getArguments()
412
414 """Return the signals dimension
415 @rtype: Data
416 """
417 return self.getDimensionAt(idx)
418
420 """Subscripting <==> signal[subscript]. Uses the dimension information for subscripting
421 @param idx: index or Range used for subscripting the signal based on the signals dimensions
422 @type idx: Data
423 @rtype: Signal
424 """
425 if isinstance(idx,slice):
426 idx = Range(idx.start,idx.stop,idx.step)
427 return _dat.Data.execute('$[$]',self,idx)
428
430 """Return the dimension of the signal
431 @param idx: The index of the desired dimension. Indexes start at 0. 0=default
432 @type idx: int
433 @rtype: Data
434 """
435 return self.getArgumentAt(idx)
436
438 """Return all the dimensions of the signal
439 @rtype: tuple
440 """
441 return self.getArguments()
442
444 """Set the dimension
445 @param idx: The index into the dimensions of the signal.
446 @rtype: None
447 """
448 return self.setArgumentAt(idx,value)
449
451 """Set all the dimensions of a signal
452 @param value: The dimensions
453 @type value: tuple
454 @rtype: None
455 """
456 return self.setArguments(value)
457 _dsc.addDtypeToClass(Signal)
460 """A Window object can be used to construct a Dimension object. It brackets the axis information stored in the
461 Dimension to construct the independent axis of a signal.
462 """
463 fields=('startIdx','endIdx','timeAt0')
464 dtype_id=197
465 _dsc.addDtypeToClass(Window)
468 """An Opaque object containing a binary uint8 array and a string identifying the type.
469 """
470 fields=('value','otype')
471 dtype_id=217
472
473
474 @property
476 "Data portion of Opaque object"
477 return self.getDescAt(0)
478 @value.setter
481
482 @property
484 "Return image from contents of data portion"
485 return self.getImage()
486
488 try: from PIL import Image
489 except: import Image
490 if _ver.ispy3:
491 from io import BytesIO as io
492 else:
493 from StringIO import StringIO as io
494 return Image.open(io(self.value.data().tostring()))
495
496 @classmethod
497 - def fromFile(cls,filename,typestring=None):
498 """Read a file and return an Opaque object
499 @param filename: Name of file to read in
500 @type filename: str
501 @param typestring: String to denote the type of file being stored. Defaults to file type.
502 @type typestring: str
503 @rtype: Opaque instance
504 """
505 import os
506 if typestring is None:
507 fn, typestring = os.path.splitext(filename)
508 f = open(filename,'rb')
509 try:
510 opq=cls(_dat.Data(_N.fromstring(f.read(),dtype="uint8")),typestring)
511 finally:
512 f.close()
513 return opq
514 _dsc.addDtypeToClass(Opaque)
517 """Specifies a units for any kind of data.
518 """
519 fields=('data','units')
520 dtype_id=211
521 _dsc.addDtypeToClass(WithUnits)
524 """Specifies error information for any kind of data.
525 """
526 fields=('data','error')
527 dtype_id=213
528 _dsc.addDtypeToClass(WithError)
531 """Specifies a help text and validation information for any kind of data.
532 """
533 fields=('data','help','validation')
534 dtype_id=194
535 _dsc.addDtypeToClass(Parameter)
540
541 -class dA0(Function):
544
548
549 -class dAMU(Function):
552
556
557 -class dCAL(Function):
560
564
565 -class dEV(Function):
568
572
576
580
581 -class dGAS(Function):
584
588
593
597
601
602 -class dME(Function):
605
609
610 -class dMP(Function):
613
614 -class dN0(Function):
617
618 -class dNA(Function):
621
622 -class dP0(Function):
625
626 -class dPI(Function):
629
630 -class dQE(Function):
633
634 -class dRE(Function):
637
641
645
646 -class dT0(Function):
649
653
657
662
667
668 -class ABS(Function):
672
673 -class ABS1(Function):
677
682
687
688 -class ACOS(Function):
692
697
698 -class ADD(Function):
702
707
712
717
718 -class AINT(Function):
722
723 -class ALL(Function):
727
732
733 -class AND(Function):
737
742
747
748 -class ANY(Function):
752
753 -class ARG(Function):
757
758 -class ARGD(Function):
762
767
772
773 -class ASIN(Function):
777
782
787
788 -class ATAN(Function):
792
797
802
807
812
817
822
827
832
837
842
847
852
857
862
867
872
877
882
887
892
897
902
907
912
917
922
933
938
943
948
953
958
963
964 -class BYTE(Function):
968
973
974 -class CASE(Function):
978
983
984 -class CHAR(Function):
988
993
998
1003
1008
1013
1018
1023
1028
1033
1038
1043
1044 -class COS(Function):
1048
1049 -class COSD(Function):
1053
1054 -class COSH(Function):
1058
1063
1068
1069 -class CVT(Function):
1073
1074 -class DATA(Function):
1078
1083
1088
1089 -class DBLE(Function):
1093
1098
1103
1108
1113
1118
1123
1128
1133
1138
1143
1144 -class DIM(Function):
1148
1153
1158
1163
1168
1169 -class DO(Function):
1173
1178
1183
1188
1193
1194 -class SIZE(Function):
1198
1199 -class KIND(Function):
1203
1208
1213
1218
1223
1228
1233
1234 -class ELSE(Function):
1238
1243
1248
1253
1258
1263
1268
1269 -class EQ(Function):
1273
1278
1283
1284 -class EQV(Function):
1288
1293
1298
1303
1308
1313
1314 -class EXP(Function):
1318
1323
1328
1329 -class FFT(Function):
1333
1338
1339 -class FIT(Function):
1343
1348
1353
1358
1359 -class FOR(Function):
1363
1368
1369 -class FUN(Function):
1373
1378
1383
1384 -class GE(Function):
1388
1393
1394 -class GOTO(Function):
1398
1399 -class GT(Function):
1403
1408
1413
1418
1419 -class HUGE(Function):
1423
1428
1433
1438
1439 -class IAND(Function):
1443
1448
1453
1458
1459 -class IF(Function):
1463
1468
1473
1474 -class IN(Function):
1478
1483
1488
1493
1494 -class INOR(Function):
1498
1503
1504 -class INOT(Function):
1508
1513
1518
1519 -class INT(Function):
1523
1528
1533
1538
1543
1548
1549 -class IOR(Function):
1553
1558
1563
1564 -class IEOR(Function):
1568
1573
1578
1583
1588
1593
1594 -class LE(Function):
1598
1599 -class LEN(Function):
1603
1608
1609 -class LGE(Function):
1613
1614 -class LGT(Function):
1618
1619 -class LLE(Function):
1623
1624 -class LLT(Function):
1628
1629 -class LOG(Function):
1633
1638
1639 -class LOG2(Function):
1643
1648
1649 -class LONG(Function):
1653
1658
1659 -class LT(Function):
1663
1668
1673
1678
1679 -class MAX(Function):
1683
1688
1693
1698
1699 -class MEAN(Function):
1703
1708
1713
1718
1719 -class MIN(Function):
1723
1728
1733
1738
1739 -class MOD(Function):
1743
1748
1753
1758
1759 -class NAND(Function):
1763
1768
1773
1774 -class NE(Function):
1778
1783
1784 -class NEQV(Function):
1788
1789 -class NINT(Function):
1793
1794 -class NOR(Function):
1798
1803
1804 -class NOT(Function):
1808
1813
1818
1823
1828
1833
1838
1843
1848
1849 -class OR(Function):
1853
1858
1859 -class OUT(Function):
1863
1864 -class PACK(Function):
1868
1873
1874 -class POST_DEC(Function):
1875 min_args=1
1876 max_args=1
1877 opcode=272
1878
1879 -class POST_INC(Function):
1880 min_args=1
1881 max_args=1
1882 opcode=273
1883
1888
1893
1898
1903
1911
1916
1921
1926
1931
1936
1944
1949
1954
1959
1964
1965 -class RAMP(Function):
1969
1974
1979
1984
1985 -class RANK(Function):
1989
1994
1995 -class READ(Function):
1999
2000 -class REAL(Function):
2004
2009
2010 -class REF(Function):
2014
2019
2024
2029
2034
2039
2040 -class RMS(Function):
2044
2049
2054
2059
2060 -class SCAN(Function):
2064
2069
2074
2079
2084
2089
2094
2099
2100 -class SIGN(Function):
2104
2109
2110 -class SIN(Function):
2114
2115 -class SIND(Function):
2119
2120 -class SINH(Function):
2124
2129
2134
2139
2144
2149
2154
2159
2164
2165 -class SQRT(Function):
2169
2174
2179
2184
2189
2194
2199
2204
2205 -class SUM(Function):
2209
2214
2219
2220 -class TAN(Function):
2224
2225 -class TAND(Function):
2229
2230 -class TANH(Function):
2234
2239
2240 -class TEXT(Function):
2241 min_args=1
2242 max_args=2
2243 opcode=344
2244
2249
2250 -class TINY(Function):
2254
2259
2264
2265 -class TRIM(Function):
2269
2274
2279
2284
2289
2294
2299
2304
2305 -class VAL(Function):
2309
2314
2319
2320 -class VAR(Function):
2324
2329
2334
2335 -class WAIT(Function):
2339
2344
2349
2354
2359
2360 -class WORD(Function):
2364
2369
2374
2375 -class ZERO(Function):
2379
2380 -class d2PI(Function):
2384
2389
2394
2399
2404
2409
2414
2419
2424
2429
2434
2439
2444
2449
2454
2459
2464
2469
2470 -class CULL(Function):
2474
2479
2484
2489
2490 -class MAP(Function):
2494
2499
2504
2509
2514
2519
2520 -class XD(Function):
2524
2529
2530 -class SORT(Function):
2534
2539
2544
2545 -class dATM(Function):
2549
2554
2555 -class dGN(Function):
2559
2560 -class dMU0(Function):
2564
2569
2574
2579
2584
2589
2594
2595 -class DSQL(Function):
2599
2600 -class ISQL(Function):
2604
2609
2614
2619
2624
2629
2634
2639
2644
2649
2654
2659
2664
2669
2674
2679
2684
2689
2694
2699
2704
2709
2714
2719
2724
2725 -class REM(Function):
2729
2734
2739
2744
2749
2754
2759
2764
2769
2774
2779
2784
2789
2794
2799
2800 from inspect import isclass as _isclass
2801 _c=None
2802 for _c in globals().values():
2803 if _isclass(_c) and issubclass(_c,Function) and _c.__name__ != 'Function':
2804 Function.opcodeToClass[_c.opcode]=_c
2805